﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CoreUtils.WIL
{
    public class Blobs
    {
        /// <summary>
        /// Find blob list in binary image
        /// </summary>
        /// <param name="src"></param>
        /// <returns>CFviBlobList</returns>
        /// <remarks>sonhs@vnext.vn</remarks>
        public static FVIL.Blob.CFviBlobList findBlobList(FVIL.Data.CFviImage src)
        {
            FVIL.Blob.CFviBlobList lsBlob = new FVIL.Blob.CFviBlobList();
            FVIL.Blob.CFviBlobResult result = new FVIL.Blob.CFviBlobResult();
            FVIL.Blob.CFviBlob parser = new FVIL.Blob.CFviBlob(src, result);
            //check validate image input
            if (FVIL.ErrorCode._SUCCESS != FVIL.Blob.CFviBlob.CheckValidity(src))
                return null;

            try
            {
                FVIL.Blob.CFviBlobParam param = parser.Param;
                param.ColorMode = FVIL.Blob.ObjectColor.WhiteFG_BlackBG;
                param.MaxBlobs = 0;
                param.MaxRows = 0;
                param.MaxRuns = 0;
                param.Neighborhood = FVIL.Blob.Neighborhood.Eight;
                param.PrecalcFeatures = 0;
                parser.Execute();
                lsBlob = parser.Result.GetBlobList();
                lsBlob.SortList(FVIL.Blob.FeatureType.AREA, FVIL.Blob.SortDirect.Descending);
            }
            catch (System.Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return lsBlob;
        }

        public static void DetectBlob(FVIL.Data.CFviImage src, ref FVIL.Blob.CFviBlob parser,
            string colorMode, string neighborhood)
        {
            FVIL.Blob.CFviBlobResult result = new FVIL.Blob.CFviBlobResult();
            parser = new FVIL.Blob.CFviBlob(src, result);

            if (FVIL.ErrorCode._SUCCESS != FVIL.Blob.CFviBlob.CheckValidity(src)) return;

            try
            {
                FVIL.Blob.CFviBlobParam param = parser.Param;
                switch (colorMode)
                {
                    case "WhiteFG":
                        param.ColorMode = FVIL.Blob.ObjectColor.WhiteFG;
                        break;
                    case "WhiteFG_BlackBG":
                        param.ColorMode = FVIL.Blob.ObjectColor.WhiteFG_BlackBG;
                        break;
                    case "BlackFG":
                        param.ColorMode = FVIL.Blob.ObjectColor.BlackFG;
                        break;
                    case "BlackFG_WhiteBG":
                        param.ColorMode = FVIL.Blob.ObjectColor.BlackFG_WhiteBG;
                        break;
                    default:
                        break;
                }

                param.MaxBlobs = 0;
                param.MaxRows = 0;
                param.MaxRuns = 0;
                switch (neighborhood)
                {
                    case "Four":
                        param.Neighborhood = FVIL.Blob.Neighborhood.Four;
                        break;
                    case "Eight":
                        param.Neighborhood = FVIL.Blob.Neighborhood.Eight;
                        break;
                    default:
                        break;
                }
                param.PrecalcFeatures = 0;
                parser.Execute();
            }
            finally
            {
                //src.Dispose();
                //result.Dispose();
                //parser.Dispose();
            }
        }

        public static FVIL.Data.CFviImage drawBlobOnImage(FVIL.Data.CFviImage src,
            List<FVIL.Blob.CFviBlobData> lsBlob)
        {
            FVIL.GDI.CFviDisplay display = new FVIL.GDI.CFviDisplay();
            display.Image = src;
            display.DisplayRect = src.Window;
            FVIL.GDI.CFviOverlay pOverlay0 = new FVIL.GDI.CFviOverlay();
            pOverlay0.Scaling = true;
            display.Overlays.Add(pOverlay0);
            foreach (FVIL.Blob.CFviBlobData data in lsBlob)
            {
                FVIL.Data.CFviPoint center = data.Center;
                FVIL.Data.CFviEllipse ellipse = data.EquivalentEllipse;
                System.String strBlobNo = System.String.Format("{0}", data.BlobNo);

                FVIL.GDI.CFviGdiPoint _center = new FVIL.GDI.CFviGdiPoint(center);
                _center.Size = new System.Drawing.Size(5, 3);
                _center.Angle = ellipse.Angle;
                _center.Pen.Color = System.Drawing.Color.FromArgb(0xFF, 0x00, 0x00);

                FVIL.GDI.CFviGdiEllipse _ellipse = new FVIL.GDI.CFviGdiEllipse(ellipse);
                _ellipse.Pen.Color = System.Drawing.Color.FromArgb(0x00, 0x00, 0xFF);

                FVIL.GDI.CFviGdiString _blobno = new FVIL.GDI.CFviGdiString();
                _blobno.Text = strBlobNo;
                _blobno.Position = center;
                _blobno.Align = FVIL.GDI.TextAlign.Left | FVIL.GDI.TextAlign.Top;
                _blobno.BkMode = FVIL.GDI.BkMode.Transparent;
                _blobno.Color = System.Drawing.Color.FromArgb(0x3F, 0x3F, 0xFF);

                pOverlay0.Figures.Add(_center);
                //pOverlay0.Figures.Add(_ellipse);
                pOverlay0.Figures.Add(_blobno);
            }

            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            display.SaveImage(dst, display.DisplayRect, 1.0);
            return dst;
        }
    }
}
